﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using SpLocalizer.Common;
using SpLocalizer.Common.DbApi;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Publishing;
using Microsoft.SharePoint.Navigation;

namespace SpLocalizer.ContentSourceProviders.SpListItems
{

    /// <summary>
    /// Translation provider for SharePoint list items
    /// </summary>
    public class SPListItemContent : AbstractContent, IDisposable
    {

        private SPList list = null;
       
        internal IEnumerable<AbstractContent> Bind(SPList list)
        {
            this.list = list;
            this.ContentTitle = String.IsNullOrEmpty(list.Title) ? list.ParentWebUrl : list.Title;
            this.ContentId = list.ID.ToString();
            this.ContentAddress = list.DefaultViewUrl;

            List<AbstractContent> BindResults = new List<AbstractContent>();
            BindResults.Add(this);
           
            return BindResults;
        }
     
        public override IEnumerable<BaseTranslationTask> BuildTranslationTasks(CultureInfo FromLanguage, CultureInfo ToLanguage)
        {
            List<BaseTranslationTask> tasksToTranslate = new List<BaseTranslationTask>();
            
                SPListItemCollection items = this.list.Items;
                foreach (SPListItem item in items)
                    foreach (SPField field in item.Fields)
                    {
                        SpListItemAbstractValueLocalizationTask TranslationTask = null;
                        if (IsFieldSupported(field)){
                            if (typeof(System.String) == field.FieldValueType){
                                TranslationTask = new SpListItemStringValueLocalizationTask();
                            }
                            else if (typeof(SPFieldUrlValue) == field.FieldValueType)
                            {
                                TranslationTask = new SpListItemFieldUrlValueLocalizationTask();
                            }
                            else if (typeof(SPFieldLookupValue) == field.FieldValueType)
                            {
                                TranslationTask = new SpListItemLookupValueLocalizationTask();
                            }
                        
                        
                        }
                                                
                        if (TranslationTask != null)
                        {                            
                            tasksToTranslate.AddRange(TranslationTask.BuildTranslationTasks(FromLanguage, ToLanguage, item, field.Id));
                        }
                    }
            


            return tasksToTranslate;
        }


        private bool IsFieldSupported(SPField field)
        {
 	        return (!field.Hidden && !field.ReadOnlyField) &&
                ((field is SPFieldText || field is SPFieldMultiLineText || field is SPFieldUrl  || field is SPFieldChoice) //|| field is SPFieldLookup
                     &&  (typeof(System.String) == field.FieldValueType || typeof(SPFieldUrlValue) == field.FieldValueType) 
                           // || typeof(SPFieldLookupValue) == field.FieldValueType)
                                       // || typeof(SPFieldLookupValueCollection) == field.FieldValueType)
                );
        }
    
        

        public override void ExportContentTranslations(BaseTranslationTask TranslationTask)
        {
            if (!(TranslationTask is SpListItemAbstractValueLocalizationTask))
                 throw new ArgumentException(String.Format("Illegal type {0} for translation task id {1}",
                    TranslationTask.GetType().ToString(), TranslationTask.TaskId));


            SPListItem ListItem = this.list.Items[((SpListItemAbstractValueLocalizationTask)TranslationTask).ItemId];


            if (this.list.HasExternalDataSource || this.list.Hidden)
                return; /// we don't support localization for BCS lists


           if (this.list.BaseType == SPBaseType.DocumentLibrary)
           {    // This is document library properties
               ExportDocumentLibraryTranslations((SpListItemAbstractValueLocalizationTask)TranslationTask, ListItem);
           }
           else
           {
               // This is Simple list
               ((SpListItemAbstractValueLocalizationTask)TranslationTask).SetFieldTextValue(ListItem);
               ListItem.SystemUpdate();
           }

         

        }


        private void ExportDocumentLibraryTranslations(SpListItemAbstractValueLocalizationTask TranslationTask, SPListItem ListItem)
        {
            SPDocumentLibrary oDocLibrary = (SPDocumentLibrary)this.list;


            PublishingPage publishingPage = null;
            // Handle check-out logic if it's a Publishing page
            if (PublishingPage.IsPublishingPage(ListItem))
            {
                publishingPage = PublishingPage.GetPublishingPage(ListItem);
                // Check out the page if it is not checked out yet.
                //
                if (publishingPage.ListItem.File.CheckOutType == SPFile.SPCheckOutType.None)
                {
                    publishingPage.CheckOut();
                }
            }
            else
            {
                if (ListItem.File!= null && ListItem.File.CheckOutType == SPFile.SPCheckOutType.None)
                    ListItem.File.CheckOut();
            }



            ((SpListItemAbstractValueLocalizationTask)TranslationTask).SetFieldTextValue(ListItem);

            ListItem.SystemUpdate();

            string checkInComment = String.Format("Automatic translation for field: {0}", this.list.Fields[((SpListItemAbstractValueLocalizationTask)TranslationTask).FieldId].Title);
            // Handle check-in & Publish logic if it's a Publishing page
            if (publishingPage != null)
            {                
                // Publish the page, and approve it if required, so that the updated 
                // values are visible on the published Web site.            
                publishingPage.CheckIn(checkInComment);
                SPFile pageFile = publishingPage.ListItem.File;
                pageFile.Publish(checkInComment);

                if (oDocLibrary.EnableModeration)
                    pageFile.Approve(checkInComment);
            }
            else
            {
                if (ListItem.File!= null)
                    ListItem.File.CheckIn(checkInComment);
            }

        }


        public override void PerformExportDone()
        {
          
        }

        public void Dispose()
        {
           // Nothing to do
        }
    }
}
